区别
1.在全局作用域下，var声明的变量会挂载到window上，而let和const不会
2.var声明的变量存在变量提升，而let和const不存在变量提升，并且let和const存在暂时性死区
3.let和const存在块级作用域
4.let和const不能重复声明变量，var可以，const声明的是常量，不可修改值，如果是对象，可以其属性





那我从3个方面来谈一下这个他们的区别和原理
首先是声明过程
遇到有var的作用域，在任何语句执行前都已经完成了声明和初始化，也就是变量提升并且拿到undefined的原因
function声明和初始化以及赋值一开始就全部完成，所以函数的变量提升优先级更高
对于let，解析器进入一个块级作用域，变量只是先完成声明，还没到初始化那步，此时在作用域提前访问，就报错
这就是暂时性死区的由来，得到解析到let那一行才初始化，如果有值，则初始化和赋值同时进行
const和class都是一样的道理

其次是内存分配
var会直接在栈内存里预分配内存空间，等到实际语句执行的时候，再存储对应的变量，如果传的是引用类型，
那么会在对内存里开启一个内存空间存储实际内容，栈内存中存放指针
let是不会再占内存里预分配空间，而且在栈内存分配变量时做一个检查，如果已经有相同的变量就报错
const也一样，不过const存储的变量不能被修改，对于基本类型，无法修改，但是对于引用类型，无法修改占内存分配的指针，但是可以修改对象里面的属性

第三个是变量提升
let const 和var三者其实会存在变量提升
let只是创建过程提升，初始化过程并没有提升，所以会产生暂时性死区。
var的创建和初始化过程都提升了，所以在赋值前访问会得到undefined
function 的创建、初始化、赋值都被提升了